﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BullsAndCows
{
    class BullsAndCows
    {
        int[] numbers;
        int attempts;

        int[] helper;
        int helperIndex;
        int hellperAttempts = 0;
        
        void GenerateHelper()
        {
            helperIndex = 0;
            hellperAttempts = 0;
            helper = new int[] { 0, 1, 2, 3 };
            ArrayShuffle.Shuffle(helper);            
        }

        void GenerateNumbers()
        {
                numbers = new int[4];
                Random rand = new Random();
                for (int i = 0; i < 4; i++)
                    numbers[i] = rand.Next() % 10;
        }

        void NewGame()
        {
            GenerateNumbers();
            GenerateHelper();
            attempts = 0;
        }
        
        string GetUserInput()
        {
            Console.WriteLine();
            return Console.ReadLine();
        }

        bool ValidateGuess(string guess)
        {
            if (guess.Length != 4)
                return false;
            for (int i = 0; i < 4; i++)
            {
                if (guess[i] < '0' || guess[i] > '9')
                    return false;
            }
            return true;
        }

        int[] GetCountOfBullsAndCows(string inputGuess)
        {
            int bulls = 0;
            int cows = 0;

            int[] guess = new int[4];
            for (int i = 0; i < inputGuess.Length; i++)
                guess[i] = (int)inputGuess[i] - (int)'0';

            for (int i = 0; i < 4; i++)
            {
                if (numbers[i] == guess[i])
                {
                    bulls++;
                    guess[i] = -1;
                }
            }
            for (int i = 0; i < 4; i++)
                if (guess[i] != -1)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        if (numbers[i] == guess[j])
                        {
                            cows++;
                            guess[j] = -2;
                            break;
                        }
                    }

                }

            return new int[] { bulls, cows };
        }

        void PrintOutput(int bulls, int cows)
        {
            if (bulls == 4)
            {
                Console.WriteLine("Congratulations! You guessed the secret number in {0} attempts.", attempts);
            }
            else
            {
                Console.WriteLine("Wrong number! Bulls: {0}, Cows: {1}", bulls, cows);
            }
        }

        void PrintHelp()
        {

            for (int i = 0; i < 4; i++)
            {

                if (helper[helperIndex % 4] == i)
                {
                    Console.Write(numbers[i]);
                }
                else
                {
                    Console.Write("*");
                }
            }
            helperIndex++;
            hellperAttempts++;
            Console.WriteLine();
        }

        public void Play()
        {
            ScoreBoard scoreBoard = new ScoreBoard();

            Console.WriteLine("Welcome to “Bulls and Cows” game.");
            Console.WriteLine("Please try to guess my secret 4-digit number.");
            Console.WriteLine("Use: 'top' to view the top scoreboard.");
            Console.WriteLine("Use: 'restart' to start a new game.");
            Console.WriteLine("Use: 'help' to cheat");
            Console.WriteLine("Use: 'exit' to quit the game.");
            Console.WriteLine("Enter 4 digit number to make a guess.");


            NewGame();
            while (true)
            {
                string UserInput = GetUserInput();

                if (ValidateGuess(UserInput))
                {
                    attempts++;
                    int[] countsOfBullsAndCows = GetCountOfBullsAndCows(UserInput);
                    PrintOutput(countsOfBullsAndCows[0], countsOfBullsAndCows[1]);
                    if (countsOfBullsAndCows[0] == 4)
                    {
                        scoreBoard.AddNew(attempts , hellperAttempts);
                        scoreBoard.Print();
                        NewGame();
                    }
                }
                else
                {
                    switch (UserInput)
                    {
                        case "top":
                            scoreBoard.Print();
                            break;
                        case "exit":
                            return;
                        case "restart":
                            NewGame();
                            break;
                        case "help":
                            PrintHelp();
                            break;
                        default:
                            Console.WriteLine("Invalid command or guess");
                            break;
                    }
                }
            }

        }
    }
}
